{% extends app.request.isXmlHttpRequest ? 'WebProfilerBundle:Profiler:ajax_layout.html.twig' : 'WebProfilerBundle:Profiler:layout.html.twig' %}

{% block toolbar %}
    {% set icon %}
        <img width="20" height="28" alt="Database" src="" />
        <span class="sf-toolbar-status{% if 50 < collector.querycount %} sf-toolbar-status-yellow{% endif %}">{{ collector.querycount }}</span>
        {% if collector.querycount > 0 %}
            <span class="sf-toolbar-info-piece-additional-detail">in {{ '%0.2f'|format(collector.time * 1000) }} ms</span>
        {% endif %}
        {% if collector.invalidEntityCount > 0 %}
            <span class="sf-toolbar-info-piece-additional sf-toolbar-status sf-toolbar-status-red">{{ collector.invalidEntityCount }}</span>
        {% endif %}
        {% if collector.cacheEnabled %}
            <span class="sf-toolbar-info-piece-additional sf-toolbar-status sf-toolbar-status-green" title="Second level cache enabled">2l cache</span>
        {% endif %}
    {% endset %}
    {% set text %}
        <div class="sf-toolbar-info-piece">
            <b>DB Queries</b>
            <span>{{ collector.querycount }}</span>
        </div>
        <div class="sf-toolbar-info-piece">
            <b>Query time</b>
            <span>{{ '%0.2f'|format(collector.time * 1000) }} ms</span>
        </div>
        <div class="sf-toolbar-info-piece">
            <b>Invalid entities</b>
            <span class="sf-toolbar-status sf-toolbar-status-{{ collector.invalidEntityCount > 0 ? 'red' : 'green' }}">{{ collector.invalidEntityCount }}</span>
        </div>
        {% if collector.cacheEnabled %}
            <div class="sf-toolbar-info-piece">
                <b>Cache hits</b>
                <span class="sf-toolbar-status sf-toolbar-status-green">{{ collector.cacheHitsCount }}</span>
            </div>
            <div class="sf-toolbar-info-piece">
                <b>Cache misses</b>
                <span class="sf-toolbar-status sf-toolbar-status-{{ collector.cacheMissesCount > 0 ? 'yellow' : 'green' }}">{{ collector.cacheMissesCount }}</span>
            </div>
            <div class="sf-toolbar-info-piece">
                <b>Cache puts</b>
                <span class="sf-toolbar-status sf-toolbar-status-{{ collector.cachePutsCount > 0 ? 'yellow' : 'green' }}">{{ collector.cachePutsCount }}</span>
            </div>
        {% endif %}
    {% endset %}
    {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %}
{% endblock %}

{% block menu %}
<span class="label">
    <span class="icon"><img src="" alt="" /></span>
    <strong>Doctrine</strong>
    <span class="count">
        <span>{{ collector.querycount }}</span>
        <span>{{ '%0.0f'|format(collector.time * 1000) }} ms</span>
    </span>
</span>
{% endblock %}

{% block panel %}
    {% if 'explain' == page %}
        {{ render(controller('DoctrineBundle:Profiler:explain', {
            'token': token,
            'panel': 'db',
            'connectionName': app.request.query.get('connection'),
            'query': app.request.query.get('query')
        })) }}
    {% else %}
        <div>
            <style scoped="scoped">
                h3 {
                    margin-bottom: 0px;
                }

                pre {
                    padding: 5px;
                }
            </style>

            {{ block('queries') }}
        </div>
    {% endif %}
{% endblock %}

{% block queries %}
    <h2>Queries</h2>

    {% for connection, queries in collector.queries %}
        <h3>Connection <em>{{ connection }}</em></h3>
        {% if queries is empty %}
            <p>
                <em>No queries.</em>
            </p>
        {% else %}
            <p>
                <button type="button" class="sf-button" onclick="expandAllQueries(this);" data-action="expand" data-connection="{{ loop.index }}">
                    <span class="border-l">
                        <span class="border-r">
                            <span class="btn-bg">Expand all queries</span>
                        </span>
                    </span>
                </button>
            </p>
            <table class="alt" id="queriesPlaceholder-{{ loop.index }}">
                <thead>
                    <tr>
                        <th onclick="javascript:sortTable(this, 0, 'queries-{{ loop.index }}')" data-sort-direction="-1" style="cursor: pointer;">#<span>&#9650;</span></th>
                        <th onclick="javascript:sortTable(this, 1, 'queries-{{ loop.index }}')" style="cursor: pointer;">Time<span></span></th>
                        <th style="width: 100%;">Info</th>
                    </tr>
                </thead>
                <tbody id="queries-{{ loop.index }}">
                {% for i, query in queries %}
                    <tr id="queryNo-{{ i }}-{{ loop.parent.loop.index }}" class="{{ cycle(['odd', 'even'], i) }}">
                        <td>{{ loop.index }}</td>
                        <td>{{ '%0.2f'|format(query.executionMS * 1000) }}&nbsp;ms</td>
                        <td>
                            <div class="query-section" data-state="collapsed" onclick="return expandQuery(this);" title="Expand query" data-target-id="code-{{ i }}-{{ loop.parent.loop.index }}" style="cursor: pointer;">
                                <img alt="+" src="" style="display: inline;" />
                                <img alt="-" src="" style="display: none;" />
                                <span style="display: none">Shrink query</span>
                                <span id="smallcode-{{ i }}-{{ loop.parent.loop.index }}">
                                    {{ query.sql|doctrine_minify_query }}
                                </span>
                            </div>
                            <div id="code-{{ i }}-{{ loop.parent.loop.index }}" style="display: none;">
                                {{ query.sql|doctrine_pretty_query(i, loop.parent.loop.index) }}
                            </div>
                            <span id="original-query-{{ i }}-{{ loop.parent.loop.index }}" style="display: none;">
                                {{ query.sql|doctrine_replace_query_parameters(query.params) }}
                            </span>
                            <small>
                                <strong>Parameters</strong>: {{ query.params|yaml_encode }} <br />
                                [<span id="expandParams-{{ i }}-{{ loop.parent.loop.index }}" onclick="javascript:toggleRunnableQuery(this);" data-target-id="original-query-{{ i }}-{{ loop.parent.loop.index }}" style="cursor: pointer;">Display runnable query</span>]<br/>
                            </small>

                            {% if query.explainable %}
                                [<a href="{{ path('_profiler', {'panel': 'db', 'token': token, 'page': 'explain', 'connection': connection, 'query': i}) }}" onclick="return explain(this);" style="text-decoration: none;" title="Explains the query" data-target-id="explain-{{ i }}-{{ loop.parent.loop.index }}" >
                                    <img alt="+" src="" style="display: inline; width: 12px; height: 12px;" />
                                    <img alt="-" src="" style="display: none; width: 12px; height: 12px;" />
                                    <span style="vertical-align:top">Explain query</span>
                                </a>]
                            {% else %}
                                This query cannot be explained
                            {% endif %}

                            {% if query.explainable %}
                                <div id="explain-{{ i }}-{{ loop.parent.loop.index }}" class="loading"></div>
                            {% endif %}
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        {% endif %}
    {% endfor %}

    <h2>Database Connections</h2>

    {% if collector.connections %}
        {% include 'WebProfilerBundle:Profiler:table.html.twig' with {data: collector.connections} only %}
    {% else %}
        <p>
            <em>No connections.</em>
        </p>
    {% endif %}

    <h2>Entity Managers</h2>

    {% if collector.managers %}
        {% include 'WebProfilerBundle:Profiler:table.html.twig' with {data: collector.managers} only %}
    {% else %}
        <p>
            <em>No entity managers.</em>
        </p>
    {% endif %}

    <h2>Second Level Cache</h2>

    {% if collector.cacheCounts %}
        {% include 'WebProfilerBundle:Profiler:table.html.twig' with {data: collector.cacheCounts} only %}

        {% if collector.cacheRegions.hits %}
            <h3>Number of cache hits</h3>
            {% include 'WebProfilerBundle:Profiler:table.html.twig' with {data: collector.cacheRegions.hits} only %}
        {% endif %}

        {% if collector.cacheRegions.misses %}
            <h3>Number of cache misses</h3>
            {% include 'WebProfilerBundle:Profiler:table.html.twig' with {data: collector.cacheRegions.misses} only %}
        {% endif %}

        {% if collector.cacheRegions.puts %}
            <h3>Number of cache puts</h3>
            {% include 'WebProfilerBundle:Profiler:table.html.twig' with {data: collector.cacheRegions.puts} only %}
        {% endif %}
    {% else %}
        <p>
            <em>No cache.</em>
        </p>
    {% endif %}

    <h2>Mapping</h2>

    {% for manager, classes in collector.entities %}
        <h3>Manager <em>{{ manager }}</em></h3>
        {% if classes is empty %}
            <p><em>No loaded entities.</em></p>
        {% else %}
            <table>
                <thead>
                <tr>
                    <th scope="col">Class</th>
                    <th scope="col">Mapping errors</th>
                </tr>
                </thead>
                <tbody>
                {% for class in classes %}
                    <tr>
                        <td>{{ class }}</td>
                        <td>
                            {% if collector.mappingErrors[manager] is defined and collector.mappingErrors[manager][class] is defined %}
                                <ul>
                                    {% for error in collector.mappingErrors[manager][class] %}
                                        <li>{{ error }}</li>
                                    {% endfor %}
                                </ul>
                            {% else %}
                                Valid
                            {% endif %}
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        {% endif %}
    {% endfor %}

    <script type="text/javascript">//<![CDATA[
        function explain(link) {
            "use strict";

            var imgs = link.children,
                target = link.getAttribute('data-target-id');

            Sfjs.toggle(target, imgs[0], imgs[1])
                .load(
                    target,
                    link.href,
                    null,
                    function(xhr, el) {
                        el.innerHTML = 'An error occurred while loading the details';
                        Sfjs.removeClass(el, 'loading');
                    }
                );

            return false;
        }

        function expandAllQueries(button) {
            var conn = button.getAttribute('data-connection'),
                queries = document.querySelectorAll('#queries-' + conn + ' .query-section'),
                i = queries.length,
                action = button.getAttribute('data-action');

            if (action == 'expand') {
                button.querySelector('.btn-bg').innerHTML = 'Collapse all queries';

                while (i--) {
                    if (queries[i].getAttribute('data-state') == 'collapsed') {
                        expandQuery(queries[i]);
                    }
                }
            } else {
                button.querySelector('.btn-bg').innerHTML = 'Expand all queries';

                while (i--) {
                    if (queries[i].getAttribute('data-state') == 'expanded') {
                        expandQuery(queries[i]);
                    }
                }
            }

            button.setAttribute('data-action', action == 'expand' ? 'collapse' : 'expand');
        }

        function expandQuery(link) {
            var sections = link.children,
                target = link.getAttribute('data-target-id'),
                targetId = target.replace('code', ''),
                queriesParameters = document.getElementById('original-query' + targetId);

            if (queriesParameters.style.display != 'none') {
                queriesParameters.style.display = 'none';
                document.getElementById('small' + target).style.display = 'inline';
                document.getElementById('expandParams' + targetId).innerHTML = 'Display runnable query';
            }

            if (document.getElementById('small' + target).style.display != 'none') {
                document.getElementById('small' + target).style.display = 'none';
                document.getElementById(target).style.display = 'inline';

                sections[0].style.display = 'none';
                sections[1].style.display = 'inline';
                sections[2].style.display = 'inline';

                link.setAttribute('data-state', 'expanded');
            } else {
                document.getElementById('small' + target).style.display = 'inline';
                document.getElementById(target).style.display = 'none';

                sections[0].style.display = 'inline';
                sections[1].style.display = 'none';
                sections[2].style.display = 'none';

                link.setAttribute('data-state', 'collapsed');
            }

            return false;
        }

        function toggleRunnableQuery(target) {
            var targetId = target.getAttribute('data-target-id').replace('original-query', ''),
                targetElement = document.getElementById(target.getAttribute('data-target-id')),
                elem;

            if (targetElement.style.display != 'block') {
                targetElement.style.display = 'block';
                target.innerHTML = 'Hide runnable query';

                document.getElementById('smallcode' + targetId).style.display = 'none';
                document.getElementById('code' + targetId).style.display = 'none';

                elem = document.getElementById('code' + targetId).parentElement.children[0];

                elem.children[0].style.display = 'inline';
                elem.children[1].style.display = 'none';
                elem.children[2].style.display = 'none';

            } else {
                targetElement.style.display = 'none';
                target.innerHTML = 'Display runnable query';

                document.getElementById('smallcode' + targetId).style.display = 'inline';
            }
        }

        function sortTable(header, column, targetId) {
            "use strict";

            var direction = parseInt(header.getAttribute('data-sort-direction')) || 1,
                items = [],
                target = document.getElementById(targetId),
                rows = target.children,
                headers = header.parentElement.children,
                i;

            for (i = 0; i < rows.length; ++i) {
                items.push(rows[i]);
            }

            for (i = 0; i < headers.length; ++i) {
                headers[i].removeAttribute('data-sort-direction');
                if (headers[i].children.length > 0) {
                    headers[i].children[0].innerHTML = '';
                }
            }

            header.setAttribute('data-sort-direction', (-1*direction).toString());
            header.children[0].innerHTML = direction > 0 ? '&#9650;' : '&#9660;';

            items.sort(function(a, b) {
                return direction*(parseFloat(a.children[column].innerHTML) - parseFloat(b.children[column].innerHTML));
            });

            for (i = 0; i < items.length; ++i) {
                Sfjs.removeClass(items[i], i % 2 ? 'even' : 'odd');
                Sfjs.addClass(items[i], i % 2 ? 'odd' : 'even');
                target.appendChild(items[i]);
            }
        }

    //]]></script>
{% endblock %}
